Internal Memory
When we talk about "internal memory" in Go (or any language), we’re referring to how data is stored and managed in the computer’s RAM while the program runs.
Go divides internal memory into several important areas:
- Stack – Small, fast memory used for function calls and local variables.
- Heap – Larger memory area used for dynamically allocated variables.
- Data Segment – For global and static variables.
- Code Segment – Where compiled machine instructions are stored.
Memory Layout
When a Go program runs, memory is roughly divided like this:
+---------------------+ <- High memory addresses
| Command Line Args |
+---------------------+
| Environment Vars |
+---------------------+
| Stack | <- Each goroutine has its own stack
+---------------------+
| Heap | <- Shared between all goroutines
+---------------------+
| Global Variables |
+---------------------+
| Program Code |
+---------------------+ <- Low memory addresses
Stack
- Stores function call frames:
- Local variables
- Function parameters
- Return addresses
- Automatically cleaned up after a function returns.
- Very fast because it works like a LIFO (Last In, First Out) structure.
- Limited in size (default goroutine stack starts small, grows automatically).
func add(a, b int) int {
result := a + b // 'result' stored on stack
return result
}
func main() {
sum := add(5, 3) // 'sum' stored on stack
fmt.Println(sum)
}
a,b, andresultlive in the stack frame ofadd().sumlives in the stack frame ofmain().
Heap
- Stores dynamically allocated memory.
- Managed by Go’s garbage collector.
- Slower than stack, but size is much bigger.
- Memory stays allocated until garbage collector removes it.
func createSlice() *[]int {
nums := []int{1, 2, 3} // allocated on heap
return &nums
}
func main() {
slicePtr := createSlice()
fmt.Println(*slicePtr)
}
numsescapes to the heap because we return a pointer to it.- Even after
createSlice()ends,numsstays in memory (heap) until GC clears it.
Data Segment
- Stores global variables and constants.
- Exists for the entire lifetime of the program
var globalCount int = 100 // stored in data segment
func main() {
fmt.Println(globalCount)
}
globalCountis stored in a fixed memory location in the data segment.
Code Segment
- Stores the compiled binary instructions of your Go program.
- Read-only for safety.
- Rarely manipulated directly by Go developers.
Stack vs Heap
| Feature | Stack | Heap |
|---|---|---|
| Speed | Fast | Slower |
| Size | Small, grows per goroutine | Large |
| Lifetime | Until function ends | Until GC cleans it |
| Management | Automatic (LIFO) | Garbage Collector |
| Best for | Local, short-lived variables | Long-lived, shared data |
Memory Escape
Go decides where variables go (stack or heap) at compile time. If a variable “escapes” a function (returned or referenced externally), it goes to the heap.
func heapExample() *int {
x := 42
return &x // escapes to heap
}
func stackExample() int {
x := 42
return x // stays in stack
}
func main() {
heapPtr := heapExample()
fmt.Println(*heapPtr)
stackVal := stackExample()
fmt.Println(stackVal)
}